package Server;

/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
import sport.PlayerManagerHome;
import sport.PlayerManagerRemote;
import sport.TeamManagerHome;
import sport.TeamManagerRemote;
import team.TeamFabric;
import team.Team;
import team.Reflectable;
import java.io.*;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.List;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import player.Player;
import player.PlayerFabric;
/**
 *
 * @author denaas
 */
public class SportServlet extends HttpServlet {

    private PlayerManagerRemote playerManager;
    private TeamManagerRemote teamManager;

    public void init() {
        try {
            InitialContext ic  = new InitialContext();
            Object ref = ic.lookup("ejb/PlayerManager");
            playerManager = ((PlayerManagerHome)PortableRemoteObject.narrow(ref, PlayerManagerHome.class)).create();
            ref = ic.lookup("ejb/TeamManager");
            teamManager = ((TeamManagerHome)(TeamManagerHome)PortableRemoteObject.narrow(ref, TeamManagerHome.class)).create();
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            /*
             * TODO output your page here. You may use following sample code.
             */
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet SportServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet SportServlet at " + request.getContextPath() + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String page = request.getParameter("page");
        String mode = request.getParameter("mode");

        if (page == null) {
            return;
        }

        if (page.equals("teams")) {
            processTeams(mode, request, response);
            return;
        }

        if (page.equals("players")) {
            processPlayers(mode, request, response);
            return;
        }

        if (page.equals("team")) {
            processTheTeam(mode, request, response);
            return;
        }

        if (page.equals("player")) {
            processThePlayer(mode, request, response);
            return;
        }
    }

    private void processTeams(String mode, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        Integer sportId = null;
        if (request.getSession().getAttribute("sport") != null) {
            sportId = (Integer) request.getSession().getAttribute("sport");
        }

        if (mode == null) {
            out.print(getTeams(sportId));
            return;
        }
        if (mode.equals("remove")) {
            try{String[] ids = request.getParameterValues("id");
            for (int i = 0; i < ids.length; ++i) {
                removeTheTeam(new Integer(ids[i]), sportId);
            }
            response.sendRedirect(response.encodeRedirectURL("teams.jsp"));
            }
            catch(Throwable ex){
                response.sendRedirect(response.encodeRedirectURL("teams.jsp"));
                return;
            }
        }
    }

    private void processPlayers(String mode, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        Integer teamId = null;
        if (request.getSession().getAttribute("teamId") != null) {
            teamId = (Integer) request.getSession().getAttribute("teamId");
        }
        Integer sportId = null;
        if (request.getSession().getAttribute("sport") != null) {
            sportId = (Integer) request.getSession().getAttribute("sport");
        }

        if (mode == null) {
            out.print(getPlayers(teamId, sportId));
            return;
        }

        if ("roster".equals(mode)) {
            out.print(getPlayersRoster(teamId, sportId));
            return;
        }

        if ("stats".equals(mode)) {
            out.print(getPlayersStats(teamId, sportId));
            return;
        }

        if (mode.equals("query")) {

            out.print(getPlayersQuery(teamId, sportId, request));
            return;
        }
        if (mode.equals("remove")) {
            try{String[] ids = request.getParameterValues("id");
            for (int i = 0; i < ids.length; ++i) {
                removeThePlayer(new Integer(ids[i]), sportId);
            }
            response.sendRedirect(response.encodeRedirectURL("players.jsp"));
            }
            catch(Throwable ex){
                response.sendRedirect(response.encodeRedirectURL("players.jsp"));
                return;
            }
        }
    }

    private void processTheTeam(String mode, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        Integer teamId = null;
        if (request.getSession().getAttribute("teamId") != null) {
            teamId = (Integer) request.getSession().getAttribute("teamId");
        }
        Integer sportId = null;
        if (request.getSession().getAttribute("sport") != null) {
            sportId = (Integer) request.getSession().getAttribute("sport");
        }

        if (mode == null) {
            out.print(getTheTeam(teamId, sportId, false));
            return;
        }
        if (mode.equals("edit")) {
            out.print(getTheTeam(teamId, sportId, true));
            return;
        }
        if (mode.equals("save")) {
            editTheTeam(teamId, sportId, request);
            response.sendRedirect(response.encodeRedirectURL("team.jsp"));
            return;
        }
        if (mode.equals("remove")) {
            removeTheTeam(teamId, sportId);
            response.sendRedirect(response.encodeRedirectURL("teams.jsp"));
            return;
        }
        if (mode.equals("add")) {
            try {
                addTeam(sportId, request);
                response.sendRedirect(response.encodeRedirectURL("teams.jsp"));
                return;
            }
            catch(Throwable ex) {
                //should create error page
                response.sendRedirect(response.encodeRedirectURL("index.html"));
                return;
            }
        }
        if (mode.equals("name")) {
            out.print(getTeamName(teamId, sportId));
            return;
        }
    }

    private void processThePlayer(String mode, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        Integer teamId = null;
        if (request.getSession().getAttribute("teamId") != null) {
            teamId = (Integer) request.getSession().getAttribute("teamId");
        }
        Integer sportId = null;
        if (request.getSession().getAttribute("sport") != null) {
            sportId = (Integer) request.getSession().getAttribute("sport");
        }
        Integer playerId = null;
        if (request.getSession().getAttribute("playerId") != null) {
            playerId = (Integer) request.getSession().getAttribute("playerId");
        }

        if (mode == null) {
            out.print(getThePlayer(playerId, teamId, sportId, false));
            return;
        }
        if (mode.equals("edit")) {
            out.print(getThePlayer(playerId, teamId, sportId, true));
            return;
        }
        if (mode.equals("save")) {
            editThePlayer(playerId, teamId, sportId, request);
            response.sendRedirect(response.encodeRedirectURL("player.jsp"));
            return;
        }
        if (mode.equals("remove")) {
            removeThePlayer(playerId, sportId);
            response.sendRedirect(response.encodeRedirectURL("roster.jsp"));
            return;
        }
        if (mode.equals("add")) {
            addPlayer(teamId, sportId, request);
            response.sendRedirect(response.encodeRedirectURL("roster.jsp"));
            return;
        }
        if (mode.equals("name")) {
            out.print(getPlayerName(playerId, teamId, sportId));
            return;
        }
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private String getTeams(Integer sportId) {
        String result = new String();

        List teams = null;
        try {
            teams = teamManager.selectMany(sportId);
        } catch (Exception ex) {

            ex.printStackTrace();
        }

        for (int i = 0; i < teams.size(); i++) {
            Team team = (Team) teams.get(i);
            result += "<tr>";
            result += "<td><input type=checkbox name='teamId' id='" + team.getId() + "'></td>";
            result += "<td nowrap='nowrap'>" + (i + 1) + "</td>";
            result += "<td class='lcol' nowrap='nowrap'>";
            result += "<nobr>";
            result += "<a href='team.jsp?teamId=" + team.getId() + "' class='team-match-link'>";
            result += "<span class='team-tag'>" + team.getName() + "</span>";
            result += "</a>";
            result += "</nobr>";
            result += "</td>";

            List attrs = team.getAttrsNames();
            for (int j = 0; j < attrs.size(); j++) {
                String attr = (String) attrs.get(j);
                if (!attr.equals("name") && !attr.equals("id") && !attr.equals("sportId")) {
                    String val = team.getAttrValueToStr(attr);
                    result += "<td class='common' nowrap='nowrap'>" + val + "</td>"; //games
                }
            }
            result += "</tr>";
        }

        return result;
    }

    private String getPlayersRoster(Integer teamId, Integer sportId) {
        String result = new String();

        List players = null;
        try {
            players = playerManager.selectMany(teamId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        
        for (int i = 0; i < players.size(); i++) {

            Player player = (Player) players.get(i);
            result += "<tr>";

            result += "<td><input type=checkbox name='playerId' id='" + player.getId() + "'></td>";
            result += "<td>" + (i+1) + "</td>";
            result += "<td><a href='player.jsp?playerId=" + player.getId() + "'>" + player.getFirstName() + " " + player.getLastName() + "</a>";
            result += "</td>";

            List attrs = player.getAttrsNames();
            for (int j = 0; j < attrs.size(); j++) {
                String attr = (String) attrs.get(j);
                if (attr.equals("position") || attr.equals("name") || attr.equals("country") || attr.equals("height") || attr.equals("weight") || attr.equals("dateOfBirth")) {
                    String val = player.getAttrValueToStr(attr);
                    result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                }
            }
            result += "</tr>";            
        }
        return result;
    }
        
    private String getPlayersStats(Integer teamId, Integer sportId) {
        String result = new String();

        List players = null;
        try {
            players = playerManager.selectMany(teamId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }

        for (int i = 0; i < players.size(); i++) {
            Player player = (Player) players.get(i);
            result += "<tr>";

            result += "<td><input type=checkbox name='playerId' id='" + player.getId() + "'></td>";
            result += "<td>" + (i+1) + "</td>";
            result += "<td><a href='player.jsp?playerId=" + player.getId() + "'>" + player.getFirstName() + " " + player.getLastName() + "</a>";
            result += "</td>";

            List attrs = player.getAttrsNames();
            for (int j = 0; j < attrs.size(); j++) {
                String attr = (String) attrs.get(j);
                if (!(attr.equals("id") ||attr.equals("teamId") ||attr.equals("firstName") ||attr.equals("lastName") ||attr.equals("position") || attr.equals("name") || attr.equals("country") || attr.equals("height") || attr.equals("weight") || attr.equals("dateOfBirth"))) {
                    String val = player.getAttrValueToStr(attr);
                    result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                }
            }
            result += "</tr>";
        }
        return result;
    }

    private String getPlayers(Integer teamId, Integer sportId) {
        String result = new String();

        List players = null;
        try {
            players = playerManager.selectMany(teamId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        
        for (int i = 0; i < players.size(); i++) {
            Player player = (Player) players.get(i);
            result += "<tr>";

            result += "<td><input type=checkbox name='playerId' id='" + player.getId() + "'></td>";
            result += "<td>" + (i+1) + "</td>";
            result += "<td><a href='player.jsp?playerId=" + player.getId() + "'>" + player.getFirstName() + " " + player.getLastName() + "</a>";
            result += "</td>";

            List attrs = player.getAttrsNames();
            for (int j = 0; j < attrs.size(); j++) {
                String attr = (String) attrs.get(j);
                if (!(attr.equals("dateOfBirth") ||attr.equals("id") ||attr.equals("teamId") ||attr.equals("firstName") ||attr.equals("lastName") ||attr.equals("position") || attr.equals("name") || attr.equals("country"))) {
                    String val = player.getAttrValueToStr(attr);
                    result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                }
            }
            result += "</tr>";
        }

        return result;
    }

    private String getPlayersQuery(Integer teamId, Integer sportId, HttpServletRequest request) {
        String result = new String();

        List players = null;
        try {
            Player plfrom = PlayerFabric.getInstance(sportId.byteValue());
            Player plto = PlayerFabric.getInstance(sportId.byteValue());
            List attrs = plfrom.getAttrsNames();
            for (int j = 0; j < attrs.size(); j++) {
                String attr = (String) attrs.get(j);
                String from, to;
                if (plfrom.getAttrType(attr) == String.class) {
                    from = request.getParameter(attr);
                    to = request.getParameter(attr);
                } else {
                    from = request.getParameter(attr + "from");
                    to = request.getParameter(attr + "to");
                }
                if (from != null) {
                    plfrom.setAttrValue(attr, castParam(plfrom, attr, from));
                }
                if (to != null) {
                    plto.setAttrValue(attr, castParam(plfrom, attr, to));
                }
            }

            players = playerManager.selectByQuery(plfrom, plto, sportId);
        } catch (Throwable ex) {

            ex.printStackTrace();
            return "<td style='text-align: center; font-size: 18pt;' colspan=15>Wrong criteria! Repeat the search with right parameters!</td>";
        }

        for (int i = 0; i < players.size(); i++) {
                Player player = (Player) players.get(i);
                result += "<tr>";

                result += "<td><input type=checkbox name='playerId' id='" + player.getId() + "'></td>";
                result += "<td>" + (i+1) + "</td>";
                result += "<td><a href='player.jsp?playerId=" + player.getId() + "'>" + player.getFirstName() + " " + player.getLastName() + "</a>";
                result += "</td>";

                List attrs = player.getAttrsNames();
                for (int j = 0; j < attrs.size(); j++) {
                    String attr = (String) attrs.get(j);
                    if (!(attr.equals("dateOfBirth") ||attr.equals("id") ||attr.equals("teamId") ||attr.equals("firstName") ||attr.equals("lastName") ||attr.equals("position") || attr.equals("name") || attr.equals("country"))) {
                        String val = player.getAttrValueToStr(attr);
                        result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                    }
                }
                result += "</tr>";
            }

        return result;
    }

    private String getTheTeam(Integer teamId, Integer sportId, boolean modeEdit) {
        String result = new String();

        Team team = null;
        try {
            team = teamManager.selectOne(teamId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        
        List attrs = team.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            if (!attr.equals("name") && !attr.equals("id") && !attr.equals("sportId")) {
                String val = team.getAttrValueToStr(attr);
                if (modeEdit) {
                    result += "<td class='score' nowrap='nowrap'><input type=text name='" + attr + "' class=picker value=" + val + "></td>";
                } else {
                    result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                }
            }
        }

        return result;
    }

    private String getThePlayer(Integer playerId, Integer teamId, Integer sportId, boolean modeEdit) {
        String result = new String();

        Player player  = null;
        try {
            player = playerManager.selectOne(playerId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        
        List attrs = player.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            if (!attr.equals("firstName") &&!attr.equals("lastName") && !attr.equals("id") && !attr.equals("sportId")) {
                
                String val = player.getAttrValueToStr(attr);
                
                if (modeEdit) {
                    if (attr.equals("teamId")) {
                        try {
                            List selectedTeams = teamManager.selectMany(sportId);
                            
                            result += "<td class='score' nowrap='nowrap'><select name='" + attr + "' size='1' class='teampicker' id='selectTeam'>";
                            
                            for (int i=0; i<selectedTeams.size(); i++){
                                Team t = (Team)selectedTeams.get(i);
                                if (teamId != null && !teamId.equals(t.getId())) {
                                    result += "<option value='" + t.getId().intValue() +"'>"+ t.getName() +"</option>";
                                }
                                else {
                                    result += "<option selected='selected' value='" + t.getId().intValue() +"'>"+ t.getName() +"</option>";
                                }
                            }                            
                                    
                            result += "</select></td>";
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }                       
                        
                    } else {
                        result += "<td class='score' nowrap='nowrap'><input type='text' name='" + attr + "' class=picker value=" + val + "></td>";
                    }
                } else {
                    if (attr.equals("teamId")) {
                        try {
                            Team selectedTeam = teamManager.selectOne(player.getTeamId(), sportId);
                            result += "<td class='common' nowrap='nowrap'>" + selectedTeam.getName() + "</td>";
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        result += "<td class='common' nowrap='nowrap'>" + val + "</td>";
                    }
                }
            }
        }

        return result;
    }

    private void editTheTeam(Integer teamId, Integer sportId, HttpServletRequest request) {
        Team team = TeamFabric.getInstance(sportId.intValue());

        List attrs = team.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            team.setAttrValue(attr, castParam(team, attr, request.getParameter(attr)));
        }

        team.setId(teamId);
        team.setSportId(sportId);
        try {
            teamManager.edit(team);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private void editThePlayer(Integer playerId, Integer teamId, Integer sportId, HttpServletRequest request) {
        Player player = PlayerFabric.getInstance(sportId.intValue());

        List attrs = player.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            player.setAttrValue(attr, castParam(player, attr, request.getParameter(attr)));
        }

        player.setId(playerId);
        try {
            playerManager.edit(player);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private void addTeam(Integer sportId, HttpServletRequest request) {
        Team team = TeamFabric.getInstance(sportId.intValue());

        List attrs = team.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            if (attr.equals("id")) {
                continue;
            }
            team.setAttrValue(attr, castParam(team, attr, request.getParameter(attr)));
        }
        team.setId(sportId);
        team.setSportId(sportId);
        try {
            teamManager.add(team);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private void addPlayer(Integer teamId, Integer sportId, HttpServletRequest request) {
        Player player = PlayerFabric.getInstance(sportId.intValue());

        List attrs = player.getAttrsNames();
        for (int j = 0; j < attrs.size(); j++) {
            String attr = (String) attrs.get(j);
            if (attr.equals("id")) {
                continue;
            }
            player.setAttrValue(attr, castParam(player, attr, request.getParameter(attr)));
        }

        player.setTeamId(teamId);
        try {
            playerManager.add(player);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private void removeTheTeam(Integer teamId, Integer sportId) {
        try {
            teamManager.remove(teamId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private void removeThePlayer(Integer playerId, Integer sportId) {
        try {
            playerManager.remove(playerId, sportId);
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    private String getTeamName(Integer teamId, Integer sportId) {
        try {
            return teamManager.selectOne(teamId, sportId).getName();
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
        return null;
    }

    private String getPlayerName(Integer playerId, Integer teamId, Integer sportId) {
        Player pl = null;
        try {
            pl = playerManager.selectOne(playerId, sportId);
            return pl.getFirstName() + " " + pl.getLastName();
        } catch (Throwable ex) {
             ex.printStackTrace();
        }
        return null;
    }

    public Object castParam(Reflectable obj, String attrName, String param) {
        if (param == null) {
            return null;
        }
        if (obj.getAttrType(attrName).equals(String.class)) {
            return param;
        }
        if (obj.getAttrType(attrName).equals(Integer.class)) {
            return new Integer(param);
        }
        if (obj.getAttrType(attrName).equals(Double.class)) {
            return new Double(param);
        }
        return null;
    }
}
